home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / storage / page / pskip.c < prev   
Encoding:
C/C++ Source or Header  |  1992-08-27  |  5.3 KB  |  211 lines

  1.  
  2. /*
  3.  *  PSKIP.C
  4.  *
  5.  *  related to internal_page.h, not internal.h
  6.  *
  7.  */
  8.  
  9. static char    pskip_c[] = "$Header: /private/postgres/src/storage/page/RCS/pskip.c,v 1.9 1992/03/05 00:41:39 hong Exp $";
  10.  
  11. #include "tmp/c.h"
  12.  
  13. #include "access/skey.h"
  14. #include "storage/buf.h"
  15. #include "storage/bufmgr.h"
  16. #include "storage/bufpage.h"
  17. #include "storage/itemid.h"
  18. #include "storage/itempos.h"
  19. #include "storage/itemptr.h"
  20. #include "storage/page.h"
  21. #include "utils/memutils.h"
  22. #include "utils/log.h"
  23.  
  24. /*
  25.  *    pskip.c        - standard buffer page traversal routines
  26.  */
  27.  
  28. ItemSubposition
  29. startpskip(db, relation, tid)
  30.     Buffer        db;
  31.     Relation    relation;
  32.     ItemPointer    tid;
  33. {
  34.     ItemSubposition    objp;
  35.     PageHeader    dp;
  36.     char        *cp;
  37.     unsigned    off;
  38.  
  39.     if (ItemPointerIsValid(tid) == false) {
  40.         elog(FATAL, "startpskip: passed NULL tid");
  41.     }
  42.     if (BufferIsValid(db)) {
  43. /*
  44.         if (db->db_lock != L_PIN)
  45.             elog(DEBUG, "startpskip: db->db_lock is 0%o",
  46.                 db->db_lock);
  47. */
  48.         IncrBufferRefCount(db);
  49.     } else if (RelationIsValid(relation) == false) {
  50.         elog(FATAL, "startpskip: NULL rdesc and db");
  51.     } else {
  52.         db = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
  53.         if (db < 0) {
  54.             elog(WARN, "startpskip: failed ReadBuffer()");
  55.         }
  56.     }
  57.     objp = (ItemSubposition)palloc(sizeof *objp);
  58.     dp = (PageHeader)BufferGetBlock(db);
  59.     objp->op_db = db;
  60.     objp->op_lpp = PageGetItemId(dp, ItemPointerSimpleGetOffsetIndex(tid));
  61.     if (ItemIdIsLock(objp->op_lpp)) {
  62.         elog(FATAL, "startpskip: cannot handle LOCK's yet!");  /* XXX */
  63.     } else if (ItemIdIsInternal(objp->op_lpp)) {
  64.         elog(FATAL, "startpskip: cannot handle itup's yet!");  /* XXX */
  65.     }
  66.     cp = (char *)dp + (*objp->op_lpp).lp_off;
  67.     /*
  68.      *    Assumes < 700 attributes--else use (tup->t_hoff & I1MASK)
  69.      * check this and the #define MAXATTS in ../h/htup.h
  70.      */
  71.     if (ItemIdIsContinuing(objp->op_lpp)) {
  72.         cp += TCONTPAGELEN;
  73.     }
  74.     off = ((HeapTuple)cp)->t_hoff;
  75.     objp->op_cp = cp + off;
  76.     if (ItemIdIsContinuing(objp->op_lpp)) {
  77.         off += TCONTPAGELEN;
  78.     }
  79.     if (objp->op_cp != (char *)LONGALIGN(objp->op_cp))
  80.         elog(FATAL, "startpskip: malformed heap tuple");
  81.     objp->op_len = (*objp->op_lpp).lp_len - off;
  82.     return (objp);
  83. }
  84.  
  85. endpskip(objp)
  86. ItemSubposition    objp;
  87. {
  88.       Assert(BufferIsValid(objp->op_db));
  89.     ReleaseBuffer(objp->op_db);
  90.     pfree(objp);
  91. }
  92.  
  93. /*
  94.  *    pskip        - skip bytes across a chain of pages
  95.  *
  96.  *    Returns -1 upon error.
  97.  */
  98.  
  99. int
  100. pskip(objp, skip)
  101. ItemSubposition    objp;
  102. unsigned long    skip;
  103. {
  104.     PageHeader    dpp;
  105.     Relation    relation;
  106.     unsigned long    pagenum;
  107.     int        lock;
  108.  
  109.     lock = objp->op_len <= skip;
  110.     Assert(BufferIsValid(objp->op_db));
  111.     while (objp->op_len <= skip) {
  112.         if (!ItemIdIsContinuing(objp->op_lpp)) {
  113.             if (objp->op_len != skip)
  114.                 elog(WARN, "pskip: %lu past end of object",
  115.                     skip - objp->op_len);    /* XXX elog */
  116.             break;
  117.         }
  118.         skip -= objp->op_len;
  119.         dpp = (PageHeader)BufferGetBlock(objp->op_db);
  120.  
  121.         pagenum = ItemPointerGetBlockNumber((ItemPointer)
  122.             (uint16 *)((char *)dpp + (*objp->op_lpp).lp_off));
  123.         /* XXX ignoring the other information */
  124. /*
  125.         pagenum = BlockIdGetBlockNumber((uint16 *)((char *)dpp +
  126.             (*objp->op_lpp).lp_off));
  127. */
  128.         relation = BufferGetRelation(objp->op_db);
  129.         ReleaseBuffer(objp->op_db);
  130.         objp->op_db = ReadBuffer(relation, pagenum);
  131.         if (RelationIsValid(objp->op_db) == false) {
  132.             elog(WARN, "pskip: failed ReadBuffer");
  133.         }
  134.         dpp = (PageHeader)BufferGetBlock(objp->op_db);
  135.         objp->op_lpp = dpp->pd_linp;    /* always first line number */
  136.         if (ItemIdIsContinuing(objp->op_lpp)) {
  137.             objp->op_cp = (char *)dpp + (*objp->op_lpp).lp_off +
  138.                 TCONTPAGELEN;
  139.             objp->op_len = (*objp->op_lpp).lp_len - TCONTPAGELEN;
  140.         } else {
  141.             objp->op_cp = (char *)dpp + (*objp->op_lpp).lp_off;
  142.             objp->op_len = (*objp->op_lpp).lp_len;
  143.         }
  144.     }
  145.     objp->op_len -= (unsigned)skip;
  146.     objp->op_cp += skip;
  147.     return (0);
  148. }
  149.  
  150. /*
  151.  *    pfill        - fill bytes across a chain of pages
  152.  *
  153.  *    Returns -1 upon error.  Otherwise, *fillp contains the
  154.  *    next PSIZE(fillp) bytes of the object.
  155.  */
  156.  
  157. int
  158. pfill(objp, fillp)
  159. ItemSubposition    objp;
  160. char        *fillp;
  161. {
  162.     unsigned long    skip;
  163.     char        *cp;
  164.     PageHeader    dpp;
  165.     Relation    relation;
  166.     unsigned long    pagenum;
  167.  
  168.     cp = fillp;
  169.     skip = PSIZE(fillp);
  170.     while (objp->op_len <= skip) {
  171.         if (!ItemIdIsContinuing(objp->op_lpp)) {
  172.             if (objp->op_len != skip)
  173.                 elog(WARN, "pfill: %lu past end of object",
  174.                     skip - objp->op_len);    /* XXX elog */
  175.             break;
  176.         }
  177.         bcopy(objp->op_cp, cp, (int)objp->op_len);
  178.         skip -= objp->op_len;
  179.         cp += objp->op_len;
  180.         dpp = (PageHeader)BufferGetBlock(objp->op_db);
  181.  
  182.         pagenum = ItemPointerGetBlockNumber((ItemPointer)
  183.             (uint16 *)((char *)dpp + (*objp->op_lpp).lp_off));
  184.         /* XXX ignoring the other information */
  185. /*
  186.         pagenum = BlockIdGetBlockNumber((uint16 *)((char *)dpp +
  187.             (*objp->op_lpp).lp_off));
  188. */
  189.         relation = BufferGetRelation(objp->op_db);
  190.         ReleaseBuffer(objp->op_db);
  191.         objp->op_db = ReadBuffer(relation, pagenum);
  192.         if (RelationIsValid(objp->op_db) == false) {
  193.             elog(WARN, "pfill: failed ReadBuffer");
  194.         }
  195.         dpp = (PageHeader)BufferGetBlock(objp->op_db);
  196.         objp->op_lpp = dpp->pd_linp;    /* always first line number */
  197.         if (ItemIdIsContinuing(objp->op_lpp)) {
  198.             objp->op_cp = (char *)dpp + (*objp->op_lpp).lp_off +
  199.                 TCONTPAGELEN;
  200.             objp->op_len = (*objp->op_lpp).lp_len - TCONTPAGELEN;
  201.         } else {
  202.             objp->op_cp = (char *)dpp + (*objp->op_lpp).lp_off;
  203.             objp->op_len = (*objp->op_lpp).lp_len;
  204.         }
  205.     }
  206.     bcopy(objp->op_cp, cp, (int)skip);
  207.     objp->op_len -= (unsigned)skip;
  208.     objp->op_cp += skip;
  209.     return (0);
  210. }
  211.